﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.UI.Xaml.Controls;

namespace IRRemoteControl
{
    public class RawIREncoder
    {
        private const int waveSampleRate = 48000;
        private const double waveSampleDuration = 1d / waveSampleRate;

        private int irBaseFrequency;
        private double irHalfCycleDuration;
        private double irCycleDuration;

        //private MediaElement sound = new MediaElement { RealTimePlayback = true };
        private MediaElement sound;

        public RawIREncoder(int irBaseFrequency)
        {
            this.irBaseFrequency = irBaseFrequency;
            this.irHalfCycleDuration = 1d / irBaseFrequency;
            this.irCycleDuration = irHalfCycleDuration * 2;
        }

        public async void SendCommand(params double[] pwls)
        {
            sound = new MediaElement { RealTimePlayback = true };
            StringBuilder diag = new StringBuilder();

            var audioData = new List<short>();

            double offset = waveSampleDuration / 2;
            for (int iPwl = 0; iPwl < pwls.Length; iPwl++)
            {
                double pwl = pwls[iPwl];

                int irSignalCount = (int)Math.Round(pwl / irHalfCycleDuration);
                for (int iSignal = 0; iSignal < irSignalCount;)
                {
                    short sample;

                    if (iPwl % 2 == 0)
                    {
                        sample = offset > irHalfCycleDuration ? short.MinValue : short.MaxValue;
                        diag.Append("w");
                    }
                    else
                    {
                        sample = -127;
                        diag.Append("-");
                    }

                    audioData.Add(sample);
                    audioData.Add(sample);

                    var prevOffset = offset;
                    offset += waveSampleDuration;
                    if (offset > irCycleDuration)
                        offset -= irCycleDuration;

                    if (!(prevOffset < irHalfCycleDuration && offset < irHalfCycleDuration || prevOffset > irHalfCycleDuration && offset > irHalfCycleDuration))
                    {
                        iSignal++;
                    }
                }
            }

            Debug.WriteLine(diag.ToString());

            var wav = new WavFile(2, waveSampleRate, 16);
            wav.AppendData(audioData.ToArray());

            try
            {
                await (await ApplicationData.Current.TemporaryFolder.GetFileAsync("cmd.wav")).DeleteAsync();
            }
            catch
            {
            }
            await wav.SaveAsync(ApplicationData.Current.TemporaryFolder, "cmd.wav");

            var soundStream = await wav.ToStream();

            sound.SetSource(soundStream, "audio/wav");
            
            sound.Play();
        }
    }
}
